﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
class LogData{
	string output= "";
	string stack = "";
	public static LogData Init(string o,string s){
		LogData log = new LogData();
		log.output = o;
		log.stack = s;
		return log;
	}
	public void Show(bool showstack){
		GUILayout.Label(output);
		if(showstack)
			GUILayout.Label(stack);
	}
}
public class GameDebug : MonoBehaviour {
	static GameDebug instace;
	public bool SetFPS;
	public int TargetFps = 60;
	public bool ShowButton;
	public static GameDebug getInstace(){
		if (instace == null) {
			instace = new GameObject("GameDebug").AddComponent<GameDebug>();
			GameObject.DontDestroyOnLoad(instace);
		}
		return instace;
	}

	void Start () {
		if (SetFPS)
			Application.targetFrameRate = TargetFps;
	}

	List<LogData> logdatas = new List<LogData>();
	void OnEnable () {
		if (GameDebug.instace != null)
			GameObject.Destroy (gameObject);
		Application.RegisterLogCallback(HandleLog);
		Object.DontDestroyOnLoad (gameObject);
	}
	
	void OnDisable () {
		// Remove callback when object goes out of scope
		//当对象超出范围，删除回调。
		Application.RegisterLogCallback(null);
	}
	
	void HandleLog (string logString,string stackTrace,LogType type) {
		logdatas.Add(LogData.Init(logString,stackTrace));
	}
	Vector2 uishow;
	bool showstack;
	bool ShowDebug;
	bool ReadToClear;
	
	public Rect windowRect = new Rect (20, 300, 120, 50);
	bool Showing;
	void OnGUI(){
		windowRect = GUILayout.Window (0, windowRect, DoMyWindow, "My Window");
	}
	void Update () {
		UpdateTick();
	}
	void DoMyWindow (int windowID) {
//		if(ShowButton == true)
//			GameDebugData.GetSD().ShowGUI();
		try{
		Color color;
		color = Color.Lerp(Color.red,Color.green,mLastFps/30);
		GUI.color = color;
		// This button is too large to fit the window
		//这个按钮比限制的窗口大
		// Normally, the window would have been expanded to fit the button, but due to
		// the GUILayout.Width call above the window will only ever be 100 pixels wide
		//通常，这个窗口将被扩展以便适应这个按钮。但是由于GUILayout.Width将只允许窗口为100像素宽
		if (!Showing && GUILayout.Button ("显示fps:"+mLastFps)){
				windowRect.height = 500;
			Showing = true;
		}
		if (Showing && GUILayout.Button ("隐藏fps:"+mLastFps)){
				windowRect.height = 50;
			Showing = false;
		}
		GUI.color = Color.white;
		if(Showing == true){
			GUILayout.BeginHorizontal("box");
			if(GUILayout.Button("Clear!!!",GUILayout.Height(50),GUILayout.Width(50)))
				ReadToClear = !ReadToClear;
			if(ReadToClear){
				if(GUILayout.Button("清理",GUILayout.Height(50),GUILayout.Width(50))){
					logdatas = new List<LogData>();
					ReadToClear = false;
				}
			}
			if(GUILayout.Button("显示详细:"+showstack,GUILayout.Height(50),GUILayout.Width(50)))
				showstack = !showstack;
			if(GUILayout.Button("显示日记:"+ShowDebug,GUILayout.Height(50),GUILayout.Width(50)))
				ShowDebug = !ShowDebug;
			GUILayout.EndHorizontal();
			if(ShowDebug){
				uishow = GUILayout.BeginScrollView(uishow);
				for(var i = 0;i < logdatas.Count;i++){
					logdatas[i].Show(showstack);	
				}
				GUILayout.EndScrollView();
			}
		}
		GUI.DragWindow ();
		}catch{
		}
	}
	private long mFrameCount = 0;
	private long mLastFrameTime = 0;
	public static long mLastFps = 0;
	private void UpdateTick()
	{
		if (true)
		{
			mFrameCount++;
			long nCurTime = TickToMilliSec(System.DateTime.Now.Ticks);
			if (mLastFrameTime == 0)
			{
				mLastFrameTime = TickToMilliSec(System.DateTime.Now.Ticks);
			}
			
			if ((nCurTime - mLastFrameTime) >= 1000)
			{
				float fps = (mFrameCount * 1.0f / ((nCurTime - mLastFrameTime) / 1000.0f));
				
				mLastFps = (long)fps;
				
				mFrameCount = 0;
				
				mLastFrameTime = nCurTime;
			}
		}
	}
	public static long TickToMilliSec(long tick )
	{
		return tick / (10 * 1000);
	}

}
public class GameDebugData{
	static GameDebugData sd;
	public delegate void callback();
	public Dictionary<string,string> logs = new Dictionary<string,string>();
	public Dictionary<string,callback> onbutton = new Dictionary<string,callback>();
	public static GameDebugData GetSD(){
		if(sd == null)
			sd = new GameDebugData();
		return sd;
	}

	static public void AddButton(string key,callback cb){
		GetSD ().addButton (key,cb);
	}
	static public void Log(string key,int log){
		GetSD().SetLog (key, log.ToString ());
	}
	static public void Log(string key,float log){
		GetSD().SetLog (key, log.ToString ());
	}
	static public void Log(string key,string log){
		GetSD().SetLog (key, log);
	}

	public void RemoveButton(string key){
		if (onbutton.ContainsKey (key))
			onbutton.Remove (key);
	}
	public void addButton(string key,callback cb){
		if (onbutton.ContainsKey (key))
			return;
		else
			onbutton.Add (key, cb);
	}
	public void SetLog(string key,string log){
		if (logs.ContainsKey (key))
			logs [key] = log;
		else
			logs.Add (key, log);
	}
	public void ShowGUI(){
		try{
		if (logs != null) {	
			foreach (KeyValuePair<string, string> kvp in logs) {
				GUILayout.Label (kvp.Key + ":" + kvp.Value);
			}
		}
		if (onbutton != null) {
			foreach (KeyValuePair<string, callback> btn in onbutton) {
				if(GUILayout.Button(btn.Key))
					btn.Value();
			}
		}
		}catch{
		}
	}
}